package com.kahriboo.log4mon.server;

import java.io.InputStream;
import java.net.Socket;

import com.kahriboo.log4mon.data.LogEventProtos;
import com.kahriboo.log4mon.data.LogEventProtos.AskLog;
import com.kahriboo.log4mon.data.LogEventProtos.LogEvent;
import com.kahriboo.log4mon.data.LogEventProtos.LogEvent.StackTrace;
import com.kahriboo.log4mon.data.LogEventProtos.LogEventArray;

public class AppenderListener extends Thread {

	private final Socket socket;

	private AppenderListener(final Socket socket) {
		this.socket = socket;
	}

	public static void runListener(final Socket socket) {
		final AppenderListener runner = new AppenderListener(socket);
		runner.start();
	}

	@Override
	public void run() {
		try {
			System.out.println("Connection of a new Appender !!");

			final InputStream buf = socket.getInputStream();

			boolean isOpen = true;
			while (isOpen) {
				try {
					final AskLog askLog = LogEventProtos.AskLog.parseDelimitedFrom(buf);

					final long fromId = askLog.getFromId();

					final LogEventProtos.LogEventArray array = getLogsArray(fromId);
					array.writeDelimitedTo(socket.getOutputStream());

				} catch (final Exception ex) {
					System.out.println("Client closed !!!!");
					isOpen = false;
				}
			}
		} catch (final Exception e) {
			e.printStackTrace();
		}

	}

	private LogEventArray getLogsArray(final long fromId) {

		final int nbLogs = rand(50);

		final LogEventArray.Builder arrayBuilder = LogEventArray.newBuilder();

		for (int i = 0; i < nbLogs; i++) {
			final LogEvent.Builder logBuilder = LogEvent.newBuilder();

			logBuilder.setId(fromId + i + 1);

			logBuilder.setClassName("AClass");
			logBuilder.setFileName("AJavaFile.java");
			logBuilder.setLevel((rand(4) + 1) * 10000);
			logBuilder.setLineNumber(rand(500));
			logBuilder.setLoggerName("com.kahriboo");
			logBuilder.setMessage("This is a cool message");
			logBuilder.setMethodName("methodName");
			logBuilder.setThreadName("ThreadName");

			if (rand(10) == 1) {
				final StackTrace.Builder stackBuilder = StackTrace.newBuilder();

				final int nbLine = rand(75);
				for (int l = 0; l < nbLine; l++) {
					stackBuilder.addLine("Stack Trace Line number " + l);
				}
				logBuilder.setThrowable(stackBuilder.build());
			}

			logBuilder.setTimeStamp(System.currentTimeMillis());

			arrayBuilder.addLogs(logBuilder.build());
		}

		return arrayBuilder.build();
	}

	public int rand(final int max) {
		return (int) (Math.random() * max);
	}
}
